The solution for creating a secondary link menu from secondary link title was working fine until I started adding more layers to my site. In addition to the secondary menu, I wanted tertiary links to appear under the secondary links on the side of my page. Unfortunately, the $secondary_links variable just contains a list of secondary menu items, and not a menu tree containing the submenus. So here is what I did (starting at the beginning):
1) Create my Primary links menu to store the site structure in under admin >> menu.
If you want to name this menu something else for your site, you will need to change it in the code below.
2) In admin >> settings >> menu set the Menu containing primary links to the menu you just created.
This will load the top level menu items into the $primary_links variable to use in your page.tpl.php file. Do what you wish with that somewhere else, like at the top of your page or something.
3) Enable the Primary links block under admin >> block.
This block was created when you made the menu. Change the Placement to whatever side you want your secondary menu tree to appear.
4) Add the following code to your block.tpl.php file before it does the printing and formatting of the block:
// check if this block is your primary links (edit this if it called something else)
if ($block->subject == "Primary links") {
// check if a secondary link menu is showing
if (strpos($block->content, '<li class="expanded">')) {
// extract the active secondary menu link for the block title
$startOfTitle = strpos($block->content, '<li class="expanded">') + 21;
$endOfTitle = strpos($block->content, '<ul', $startOfTitle);
$block->subject = substr($block->content, $startOfTitle, $endOfTitle - $startOfTitle);
// trim off the final </ul> so we can search for the nested one
$lastCloseUL = strrpos($block->content, "</ul>");
$block->content = substr($block->content, 0, $lastCloseUL);
// extract the secondary menu tree from under the active secondary menu item
$startOfMenu = $endOfTitle;
$endOfMenu = strrpos($block->content, "</ul>") + 5;
$block->content = substr($block->content, $startOfMenu, $endOfMenu - $startOfMenu);
} else return; // secondary link menu, so you don't want to show the block
}
This is assuming that your theme is formatting menus and menu_trees like this:
<ul class="menu">
<li class="collapsed"><a href="/drupal-4.7.2/about" title="Information About our Group">About Us</a></li>
<li class="leaf"><a href="/drupal-4.7.2/event" title="">Community Events</a></li>
<li class="expanded"><a href="/drupal-4.7.2/members" title="" class="active">Members</a>
<ul class="menu">
<li class="collapsed"><a href="/drupal-4.7.2/members/committees" title="">Committees</a></li>
<li class="collapsed"><a href="/drupal-4.7.2/members/projects" title="">Projects</a></li>
</ul>
</li>
<li class="leaf"><a href="/drupal-4.7.2/contact" title="">Contact Us</a></li>
</ul>
If the menu code is different, you will need to replace the things that are searched for above. For this example menu, the code would show a block with Members as the title, and two menu links of Committees and projects. Simply, the code is extracting the active secondary tree from your menu, and discarding all the primary links, which you will be showing on some other part of the page.
What do you guys think of this solution? Is there an easier way to do it?
Comments
???
Are you just trying to show a secondary (and possibly tertiary) menu? The following code will create a block with a menu tree starting below the active item and the the active title as the block title.
If your primary menu structure looked like this, and you were currently on '2'
then the block would look like this:
That does seem easier...
... but I can't seem to get it to work. At least not in 5.1.
Secondary links on Drupal 5
Is the only way to create a secondary link is to insert php? Drupal can't do this automatically? I can't seem to create a secondary link.
Suz2008
Few Queries ....
Hi mccaffry and rz
Thanks for this thread I am looking for a similar solution. I tried mccaffry's solution but there seems to be some problems with that:
1. the block apperas only when I click a secondary menu item. That's fine but it appears with all the items under the primary link. So if I have menu like
the block is appearing when I am clicking on "a" and its showing the block heading as "1" and all the entries inside 1 with its children and grandchildren.
(I have not expanded the primary menu. If I keep it expanded then on clicking any primary link whole primary menu comes up with title as the first secondary link.)
What I am interested in is that when I click on "a" only a's children should come in the block.
About rz's solution:
where should I write that code???
This is my solution
Works perfectly for me. I used mccaffry's code and made some modifications.
Great help, thanks
This code works for me
Excellent code thanks, but i have a problem i thought you may have the answer to...
On my site i I have horizontal Top Nav (Primary Links) of
Home : About Us : Staff : Students : Contact Us
I use the code in the post above to display the secondary (context) links in the left sidebar
So if i click in the 'About Us' in the Primary Links, the Left Sidebar will display:
About Us
- Item 1
- Item 2
- Item 3
- Item 4
This is great. The only problem is that i have children within Item 1 - 4, and when i click on them they do not appear.
Any ideas.
Im using Drupal 5.0, could this be the problem. Would the children appear on your site?
Many thanks in advance if you can help...
Djax
On my Drupal 4.7 site the
On my Drupal 4.7 site the children (level 3) did appear. I'm just about to upgrade my site to 5.0 and will let you know if I get it to work.
Problems with this method on multilingual site
I have problems with getting this to work on an multilingual site. I use module
LocalizationLocalizer (great module by the way) and uses url rewrite as this:sv/generell-information
en/general-information
Somehow it only works for one of the languages (sv, Swedish). When I try to use this on the english version none of the submenu items are visible. I have also tried to change the menu item url to node/58 which is the node corresponding to sv/generell-information. Anyone knows how to solve this or can point me to another solution which can do the following:
- primary menu should be in top of site
- secondary menu should be in left column and have different menu items for each top menu item
- should be able to handle multilingual url-rewrite
- should be able to handle multilinugal menu items
Almost there...
I figured out what the problem with the invisible secondary_links was. It was an template error by myself that caused the problem. :)
The above code handles the following:
[yes] primary menu should be in top of site
[yes] secondary menu should be in left column and have different menu items for each top menu item
[no] should be able to handle multilingual url-rewrite
[yes] should be able to handle multilinugal menu items
The code above works on multilingual sites - but not with multilingual url rewrites. Instead of getting en/general-information I get the Swedish url sv/generell-information. So the menu title are translated but not the url. I'll try to fix this and post it here if I can find a solution to the problem.
Six months later...
Gah, I just made my own code that used a while loop to recurse up the menu tree ... I didn't realise you could just get the active trail and grab the root item!
Here's my code, it has a few less IF statements since it only runs when it's a child of the primary links menu. I don't check for the name of the block first, either, since it's intended to be pasted directly into a block.
++Andy
This code is also woking in
This code is also woking in Drupal 5 well
--------------
www.bytek.biz
www.interesno.name
Upgrade note
Just for the sake of completeness I'll note that the _ at the start of _menu_get_active_trail() denotes that it's an internal function and shouldn't be used by other code. In theory the function's behaviour could change without warning in future updates.
However, in this case it looks like the developers have realised that it's a useful (and commonly used) function - as of drupal 6 the function has changed to menu_get_active_trail(). Looks like the other functions are still there, so it should operate with the removal of that leading underscore, but I'm not running a D6 site myself so I can't promise.
--Andy
Developing Drupal websites for Livelink New Media since 2007
++Andy
Not working in D6
While menu_get_active_trail() has made the API in D6 menu_in_active_trail() is gone.
Backwards compatibility is for pussies
I guess you'd do something like this instead then:
EDIT: This works in fundamentally the same way as rapidsynergy suggested here, though he makes use of the theme() function to save loading and rendering the menu by hand (and he also uses the 5.x _menu_get_active_trail() function).
--Andy
Developing Drupal websites for Livelink New Media
++Andy
Thanks for the chuckle
indeed!
And I got tired of fiddling with PHP snippets: the Local Menu module (D6 only) provides the functionality looked for in this thread. And it works (with a minor quibble on nodes that are references from several menu items).
Quick block
Great thread- great ideas.
Here's my solution reworking some of the ideas already proposed. Create a custom block with the following code:
Works like a charm for me.
Output Just One Level of Navigation and Not Whole Tree
I'm new to drupal and I wanted to know how to control third level navigation. Especially, if I wanted to place it somewhere else on the page. This is really cool. It worked great. I just changed the last bit to $active_trail[2] and I was good to go. I'm good for my current project as it will only go to a third level. I want to make a portfolio with navigation something like http://www.31three.com/go/main/work/4/ for a customer. And this will do the trick.
For future projects though I have an issue. I guess if I had a fourth level and all I wanted was the third to output I wouldn't know how to do that. Is there a way to output just one level of navigation and not the whole tree, while still being able to target levels? After the first and second level. Once we get to third and beyond is there a way to just output that levels navigation? Great thread.
Thanks.
Check other thread
Hi seanHodge,
It looks like you already found the other thread on this at http://drupal.org/node/86890.
Best,
Eric
That is great!
This works like a charm.
I have a question you might answer:
I want to show the primary link as well. Any idea how to implement this?
Thanks!
How to theme menu tree as tabs
Very useful thread -- this does almost exactly what I need, but I would like to style the fifth level of my menu tree as per menu_local_tasks, that is, themed as tabs within the body of the page. Any hints on how to do this?
Thanks!
active class for level 1
hi rapidsynergy
how can you adapt that code to make sure level 1 is marked 'active' when using that code?
Also if level 3, level 4, etc exist, how can you alter the code in order to just show that particular level?
thanks in advance
mm
drupal 5
im just wondering if this would work in drupal 5 and also if it matters the blue marine theme.
A fully working solution
A fully working solution like this for drupal 6 would be much appreciated. The code in a comment above doesn't work unfortunately (even with the suggested modification.
Everything else I need is working OK in drupal 6, I'd rather not have to go back to 5 just for a block heading :-(
Drupal 5 custom block PHP
None of the above solutions were really what I wanted, but they did help me figure out how to do what I wanted; have a custom block show a menu tree of sibling menu items.
Create a custom block—I titled mine 'In This Section'—and type in the following PHP code as the body of the block:
Hope this is helpful.
Jonathan M. Lane
OpenConcept Consulting Inc. http://www.openconcept.ca/
subscribe
subscribe
Custom module for secondary menu block
Based on kingandy's code I made the same block but now by writing a small custom module (name: 'secondarymenu'). IMHO this is better practice than writing php code in a block. It also gives standard theming for the block title.
The block shows the secondary menu and below of the current page. The block title is name of the corresponding primary menu item.
Below is the code for the secondarymenu.module file, I guess you can make the secondarymenu.info file yourselves.
-- Erik
-- Erik
module
you could use Menu Restricter with min. level 2 and dept 1 in the settings.
A simple, less-elegant fix to my problem
I had a similar problem to others, I think, in that I have a tabbed menu along the top and a submenu down the side, with the submenu holding everything that isn't in the tabbed menu along the top. Of course, just displaying the secondary tier and displaying the 3rd, 4th, ... nth tiers in other areas isn't terrbily useful for me.
I wasn't getting much joy at all out of the previous solutions - probably because I misunderstood them - so I went ahead and did this fix for an intranet and I think it may or may not help someone else.
I created a function in my theme's template.php file, and called it from my other template files as appropriate. This is enough for me as it's not going to be changing anytime soon.
It's some simple recursion and does the trick for me. It doesn't deal with anything beyond the basics, it doesn't check against always expanded links or utilise theme related calls or anything like that, but it should be simple enough to include since everything is available in the $item array.
I'm figuring I'm going to kick myself when someone just points me to something in core that already does this, but I didn't find it my 30 minutes of looking :p
If you like you could do something very similar in a block and have it operate through Drupal's block management as appropriate.
Hope this helps someone.
Reg: Secondary Menu Block
Thanks,
It was very useful
Instead of the standard
Instead of the standard first-level-only secondary menu in D5/D6:
theme('links', $secondary_links)I'm using this in D5:
theme('menu_tree', variable_get('menu_secondary_menu', 0))And for D6:
theme('menu_tree', menu_tree('secondary-links'))(in order to see the active sub-menu items)
Great help bro, no big code
Great help bro, no big code needed
Does not work here on
Does not work here on D6.
print theme('menu_tree', menu_tree('secondary-links'))The only output is an empty ul:
However, #comment-942096 does work!
Just in case people find
Just in case people find this thread: http://drupal.org/project/menu_block is awesome!
Tertiary within secondary?
My tertiary links are displaying below my secondary links:
Is there any way to display the tertiary links within the secondary links menu? (Display the children of the secondary links which are children of the primary links)
So it would be:
Thanks!